import app from "~/constants/app";
import { IHttpResponse, IObject } from "~/types/interface";
import { getToken } from "./cache";
import router from "~/router";
import axios, { AxiosRequestConfig } from "axios";
import qs from "qs";
import { getValueByKeys } from "./utils";
import { layer } from "@layui/layui-vue";

const http = axios.create({
    baseURL: app.api,
    timeout: app.requestTimeout
});

http.interceptors.request.use(
    function (config: any) {
        config.headers["X-Requested-With"] = "XMLHttpRequest";
        config.headers["Request-Start"] = new Date().getTime();
        const token = getToken();
        if (token) {
            config.headers["token"] = token;
        }
        if (config.method?.toUpperCase() === "GET") {
            config.params = { ...config.params, _t: new Date().getTime() };
        }
        if (Object.values(config.headers).includes("application/x-www-form-urlencoded")) {
            config.data = qs.stringify(config.data);
        }
        return config;
    },
    function (error) {
        return Promise.reject(error);
    }
);
http.interceptors.response.use(
    (response) => {
        // 响应成功
        if (response.data.code === 0) {
            return response;
        }

        // 错误提示
        layer.msg(response.data.msg, { icon: 2 });

        if (response.data.code === 401) {
            //自定义业务状态码
            redirectLogin();
        }

        return Promise.reject(new Error(response.data.msg || "Error"));
    },
    (error) => {
        const status = getValueByKeys(error, "response.status", 500);
        const httpCodeLabel: IObject<string> = {
            400: "请求参数错误",
            401: "未授权，请登录",
            403: "拒绝访问",
            404: `请求地址出错: ${getValueByKeys(error, "response.config.url", "")}`,
            408: "请求超时",
            500: "API接口报500错误",
            501: "服务未实现",
            502: "网关错误",
            503: "服务不可用",
            504: "网关超时",
            505: "HTTP版本不受支持"
        };
        if (error && error.response) {
            console.error("请求错误", error.response.data);
        }
        if (status === 401) {
            redirectLogin();
        }
        return Promise.reject(new Error(httpCodeLabel[status] || "接口错误"));
    }
);

const redirectLogin = () => {
    router.replace("/login");
    return;
};

export default (o: AxiosRequestConfig): Promise<IHttpResponse> => {
    return new Promise((resolve, reject) => {
        http(o)
            .then((res) => {
                return resolve(res.data);
            })
            .catch(reject);
    });
};
